package com.quan.TemplateEditor.service;

import com.quan.TemplateEditor.interfaces.jucInterface;
import org.springframework.stereotype.Service;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Service
public class jucService implements jucInterface {
    private int counter = 0;

    /**
     * 实现线程的三种方式  继承Thread类 实现runnable Callable接口
     */
    public void testNewThread() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("=====");
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
    }

    /**
     * cas的aba问题
     */
    public void testCASABA() {
        AtomicStampedReference<Integer> atomicStampedRef = new AtomicStampedReference<>(1, 0);
        int oleStamp = atomicStampedRef.getStamp();
        Integer oleReference = atomicStampedRef.getReference();
        atomicStampedRef.compareAndSet(oleReference, oleReference + 1, oleStamp, oleStamp + 1);

    }

    /**
     * 测试Reentranlock问题
     */
    public void testReentranlock() {
        ReentrantLock reentrantLock = new ReentrantLock();
        reentrantLock.lock();
        System.out.println("===");
        reentrantLock.unlock();
    }

    /**
     * 测试reentrantReadWriteLock
     */
    public void testReentranReadWriteLock() {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
        lock.readLock().lock();
        System.out.println("read");
        lock.readLock().unlock();

        lock.writeLock().lock();
        System.out.println("write");
        lock.writeLock().unlock();

    }

    public void testFutureTask() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future submit = executorService.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                return 1;
            }
        });
        Integer i = (Integer) submit.get();
    }

    public void testExecutor() {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            Runnable worker = new Runnable() {
                @Override
                public void run() {
                    System.out.println("=");
                }
            };
            executor.execute(worker);
        }
        executor.shutdown(); // This will make the executor accept no new threads and finish all existing threads in the queue
        while (!executor.isTerminated()) { // Wait until all threads are finish,and also you can use "executor.awaitTermination();" to wait
        }
        System.out.println("Finished all threads");
    }

}
